package ae.pcfc.cldos.online.wf.service.client.provider;

import java.util.Map;

import javax.annotation.Resource;

import org.springframework.util.StringUtils;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.SoapMessage;

import ae.pcfc.cldos.online.wf.ConstantsWF;
import ae.pcfc.cldos.online.wf.Utils;
import ae.pcfc.cldos.online.wf.exception.WFException;
import ae.pcfc.cldos.online.wf.service.client.BaseWF;
import ae.pcfc.cldos.online.wf.service.client.vo.base.BaseAppDataVO;
import ae.pcfc.cldos.online.wf.service.client.vo.base.BaseGVariablesVO;
import ae.pcfc.cldos.online.wf.service.client.vo.base.BaseSubmitGVariablesVO;
import ae.pcfc.cldos.online.wf.service.client.vo.base.CompleteStepVO;
import ae.pcfc.cldos.online.wf.service.client.vo.base.LaunchIncedentVO;
import ae.pcfc.cldos.online.wf.service.types.ArrayOfVariable;
import ae.pcfc.cldos.online.wf.service.types.CompleteStep;
import ae.pcfc.cldos.online.wf.service.types.CompleteStepResponse;
import ae.pcfc.cldos.online.wf.service.types.LaunchIncident;
import ae.pcfc.cldos.online.wf.service.types.LaunchIncidentResponse;
import ae.pcfc.cldos.online.wf.service.types.ObjectFactory;

public abstract class BaseWFImpl implements BaseWF {

	protected WebServiceTemplate wsTemplate;
	protected Map<String, String> webServicesEndPointsMap;
	protected String formsAppURL;
	protected String ultimusDefaultUser;

	/**
	 * @param webServicesEndPointsMap
	 *            the webServicesEndPointsMap to set
	 */
	@Resource(name = "webServicesEndPointsMap")
	public void setWebServicesEndPointsMap(Map<String, String> webServicesEndPointsMap) {
		this.webServicesEndPointsMap = webServicesEndPointsMap;
	}
	/**
	 * @param formsAppURL the formsAppURL to set
	 */
	@Resource(name = "formsAppURL")
	public void setFormsAppURL(String formsAppURL) {
		this.formsAppURL = formsAppURL;
	}
	
	/**
	 * @param ultimusDefaultUser the ultimusDefaultUser to set
	 */
	@Resource(name = "ultimusDefaultUser")
	public void setUltimusDefaultUser(String ultimusDefaultUser) {
		this.ultimusDefaultUser = ultimusDefaultUser;
	}
	
	/**
	 * @param wsTemplate
	 *            the wsTemplate to set
	 */
	@Resource(name = "wsTemplate")
	public void setWsTemplate(WebServiceTemplate wsTemplate) {
		this.wsTemplate = wsTemplate;
	}

	public <T1 extends BaseSubmitGVariablesVO, T2 extends BaseAppDataVO> 
		Integer launchIncident(String processCode, LaunchIncedentVO wfBaseVo, T1 gVars, T2 appData) {
		
		String classURIValue = webServicesEndPointsMap.get(processCode);
		
		gVars.setgFormsAppURL(formsAppURL);
			
		if(!StringUtils.hasText(wfBaseVo.getStrUserName()))
		{
			wfBaseVo.setStrUserName(ultimusDefaultUser);
		}

		
		LaunchIncident incident = new LaunchIncident();
		incident.setStrUserName(wfBaseVo.getStrUserName());
		incident.setStrSummary(wfBaseVo.getStrSummary());
		
		
		ArrayOfVariable arrGVar = Utils.convertToWFVariable(gVars);
		ArrayOfVariable arrAppData = Utils.convertToWFVariable(appData);
		
		ObjectFactory factory = new ObjectFactory();
		ArrayOfVariable arrayOfVariable = factory.createArrayOfVariable();
		arrayOfVariable.getVariable().addAll(arrGVar.getVariable());
		arrayOfVariable.getVariable().addAll(arrAppData.getVariable());
		
		incident.setVarList(arrayOfVariable);
		
		
		LaunchIncidentResponse response = (LaunchIncidentResponse) wsTemplate
				.marshalSendAndReceive(classURIValue,incident,
						new WebServiceMessageCallback() {

							public void doWithMessage(WebServiceMessage message) {
								((SoapMessage) message)
										.setSoapAction(ConstantsWF.LAUNCH_INCIDENT_SOAP_ACTION);
							}
						});
		if (response.getNIncidentNo() <= 0) {
			throw new WFException(response.getStrError());
		}
		return response.getNIncidentNo();

	}
	
	public  <T1 extends BaseGVariablesVO, T2 extends BaseAppDataVO>  void 
		completeStep(String processCode, CompleteStepVO completeStepVO, T1 gVars, T2 appData) {
		
		String classURIValue = webServicesEndPointsMap.get(processCode);
		
		if(!StringUtils.hasText(completeStepVO.getStrUserName()))
		{
			completeStepVO.setStrUserName(ultimusDefaultUser);
		}
			
		CompleteStep step = new CompleteStep();
		step.setStrUserName(completeStepVO.getStrUserName());
		step.setNIncidentNumber(completeStepVO.getnIncidentNumber());
		step.setStrStepName(completeStepVO.getStrStepName());
		step.setStrSummary(completeStepVO.getStrSummary());
		step.setStrMemo(completeStepVO.getStrMemo());
		
		ArrayOfVariable arrGVar = Utils.convertToWFVariable(gVars);
		
		
		ObjectFactory factory = new ObjectFactory();
		ArrayOfVariable arrayOfVariable = factory.createArrayOfVariable();
		arrayOfVariable.getVariable().addAll(arrGVar.getVariable());
		if(appData!=null){
			ArrayOfVariable arrAppData = Utils.convertToWFVariable(appData);
			arrayOfVariable.getVariable().addAll(arrAppData.getVariable());
		}
		step.setVarList(arrayOfVariable);
		CompleteStepResponse response = (CompleteStepResponse) wsTemplate
				.marshalSendAndReceive(classURIValue,step,
						new WebServiceMessageCallback() {

							public void doWithMessage(WebServiceMessage message) {
								((SoapMessage) message)
										.setSoapAction(ConstantsWF.COMPLETE_STEP_SOAP_ACTION);
							}
						});
		if (!response.isCompleteStepResult()) {
			throw new WFException(response.getStrError());
		}
	}
}
